/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Container_NodeQueue_h
#define SBJ_Container_NodeQueue_h

#include "SBJ/Container/Node.h"

#include <boost/noncopyable.hpp>

#include <stddef.h>

namespace SBJ
{

/*
Class: NodeQueue

NodeQueue is a replacement (not drop-in) for an std::list.
Use NodeQueue where you require polymorphic or variable types
in the list without paying the overhead of double allocation
(object and list entry).

Use the template paramter to enforce the use of a particular
inheritence tree.

The push methods adopt the node and the pop orphan the node.
Front and Back do NOT orphan the object. They return 0 if list
is empty.
*/

template < typename T >
class NodeQueue : private boost::noncopyable
{
public:
	NodeQueue( void );

	~NodeQueue( void );

	size_t size( void ) const;

	bool empty( void ) const;

	const T* front( void ) const;

	const T* back( void ) const;

	T* front( void );

	T* back( void );

	void clear( void );

	void push_front( T* node );

	void push_back( T* node );

	T* pop_back( void );

	T* pop_front( void );

private:
	typedef Node< T > Node;

	Node* pop( Node* node );
	void push_after( Node* where, Node* node );
	void push_before( Node* where, Node* node );

	Node m_head;
	Node m_tail;
	size_t m_size;
	size_t m_achievedSize;
};

}

#include "SBJ/Container/NodeQueue.inl"

#endif